package math;

import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;

/**
 * @author xiaohuan
 * @date 2023/10/24
 */
@Component
public class BigDecimalUtil {
    /**
     * BigDecimal加法
     * @param b1
     * @param bn
     * @return
     */
    public static BigDecimal safeAdd(BigDecimal b1, BigDecimal... bn) {

        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        if (null != bn) {
            for (BigDecimal b : bn) {
                b1 = b1.add(null == b ? BigDecimal.ZERO : b);
            }
        }
        return b1;

    }

    /**
     * BigDecimal的安全减法运算
     *
     * @param isZero 减法结果为负数时是否返回0，true是返回0（金额计算时使用），false是返回负数结果
     * @param b1     被减数
     * @param bn     需要减的减数数组
     * @return
     */
    public static BigDecimal safeSubtract(Boolean isZero, BigDecimal b1, BigDecimal... bn) {

        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        BigDecimal r = b1;
        if (null != bn) {
            for (BigDecimal b : bn) {
                r = r.subtract((null == b ? BigDecimal.ZERO : b));
            }
        }
        return isZero ? (r.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : r) : r;

    }
    /**
     * BigDecimal的乘法运算封装
     *
     * @param b1
     * @param b2
     * @return
     */
    public static <T extends Number> BigDecimal safeMultiply(T b1, T b2) {
        if (null == b1 || null == b2) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(b1.doubleValue()).multiply(BigDecimal.valueOf(b2.doubleValue()));
    }
    /**
     * BigDecimal的除法运算封装，如果除数或者被除数为0，返回默认值 默认返回小数位后6位，用于金额计算 2017年3月23日下午4:59:29
     *
     * @param b1
     * @param b2
     * @param defaultValue
     * @return
     */
    public static <T extends Number> BigDecimal safeDivide(T b1, T b2, BigDecimal defaultValue) {
        if (null == b1 || null == b2) {
            return defaultValue;
        }
        try {
            return BigDecimal.valueOf(b1.doubleValue()).divide(BigDecimal.valueOf(b2.doubleValue()), 6, RoundingMode.HALF_UP);
        } catch (Exception e) {
            return defaultValue;
        }
    }
    /**
     * BigDecimal的乘法运算封装
     * @param b1
     * @param bn
     * @return
     */
    public static BigDecimal safeMultiply(BigDecimal b1, BigDecimal... bn) {
        if (null == b1) {
            b1 = BigDecimal.ZERO;
        }
        if (null != bn) {
            for (BigDecimal b : bn) {
                b1 = b1.multiply(null == b ? BigDecimal.ZERO : b);
            }
        }
        return b1;

    }

    public static boolean safeEqual(BigDecimal a, BigDecimal b) {
        if (a == null && b == null) {
            return true;
        }
        if (a == null || b == null) {
            return false;
        }
        return a.compareTo(b) == 0;

    }

    public static BigDecimal setZero(BigDecimal a) {
        return Objects.isNull(a) ? BigDecimal.ZERO : a;

    }

    /**
     * 去除小数点末尾的0
     * @param a
     * @return
     */
    public static BigDecimal stripTrailingZeros(BigDecimal a) {
        a = Objects.isNull(a) ? BigDecimal.ZERO : a;
        return a.stripTrailingZeros();

    }
    /**
     * BigDecimal转换为字符串
     * @param a
     * @return
     */
    public static String toString(BigDecimal a) {
        a = Objects.isNull(a) ? BigDecimal.ZERO : a;
        return a.stripTrailingZeros().toPlainString();

    }
    /**
     * 去除小数点末尾的0,四舍五入保留两位小数
     * @param a
     * @return
     */
    public static BigDecimal setRoundTwo(BigDecimal a) {
        a = Objects.isNull(a) ? BigDecimal.ZERO : a.setScale(2,RoundingMode.HALF_UP);
        return a.stripTrailingZeros();

    }
    /**
     * 计算百分比比率（a/b*100）
     *
     * @param b1
     * @param b2
     * @param defaultValue
     * @return
     */
    public static <T extends Number> BigDecimal calculateRate(T b1, T b2, BigDecimal defaultValue) {
        if (null == b1 || null == b2) {
            return defaultValue;
        }
        try {
            BigDecimal divide = BigDecimal.valueOf(b1.doubleValue()).divide(BigDecimal.valueOf(b2.doubleValue()), 6, RoundingMode.HALF_UP);
            return divide.multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static void main(String[] args) {
        BigDecimal bigDecimal = new BigDecimal("1.000000");
        System.out.println(Objects.equals(bigDecimal,BigDecimal.ONE));
    }
}
